home *** CD-ROM | disk | FTP | other *** search
- (*===========================================================================*)
- (* Execute DOS command *)
- (* *)
- (* Copyright 1989, 1990, 1991 by H. Roy Engehausen. All rights reserved. *)
- (* *)
- (*===========================================================================*)
-
- {$UNDEF DEBUG}
- {$UNDEF DEBUG_2} (* Server names *)
- {$UNDEF DEBUG_3} (* Server names again *)
- {$UNDEF MEMSIZE}
-
- {$DEFINE POINT_CHK}
-
- {$O+}
-
- UNIT BBEXDOS;
-
- INTERFACE
-
- PROCEDURE exec_dos(cmd_string : STRING);
-
- IMPLEMENTATION
-
- USES
- CRT,
- DOS,
- bbdummy,
- bbexport,
- bbimport,
- bbmdata,
- bbmess,
- bbmfi,
- bbmisc,
- bbmisc2,
- bbmisc3,
- bbmisc5,
- bbrunerr,
- bbsdata,
- bbsema2,
- bbstr,
- bbtime,
- bbwin;
-
-
- (*===========================================================================*)
- (* Execute a dos program *)
- (*===========================================================================*)
-
- PROCEDURE exec_dos(cmd_string : STRING);
-
- CONST
- max_block = 4095;
- overage = 16;
-
- TYPE
- param_block_type = RECORD (* DOS parameter block *)
- Environment_Ptr : WORD;
- Command_Line_Ptr : POINTER;
- FCB1 : POINTER;
- FCB2 : POINTER;
- END;
-
- VAR
- d_err : INTEGER;
- i : INTEGER;
- j : WORD;
- opt_string : str8;
- p : POINTER;
- param_block : param_block_type;
- program_name : file_name_str;
- regs : REGISTERS;
- s : STRING[10];
- save_cons : BOOLEAN;
- save_pchn : STRING[2];
- save_port : port_block_ptr;
- server_mode : BOOLEAN;
- server_name : STRING[8];
- swap_bot : WORD;
- swap_top : WORD;
- swap_file : FILE;
- swap_size : WORD;
-
- PROCEDURE clean_up;
- BEGIN;
- active_tcb^.tcb_console := save_cons;
- active_port := save_port;
- active_tcb^.tcb_port := active_port;
- active_tcb^.port_chan_s := save_pchn;
- free_semaphore(semaphore_interrupts);
- END;
-
- BEGIN;
-
- (*-----------------------------------------------------------------------*)
- (* Server mode? *)
- (*-----------------------------------------------------------------------*)
-
- s := SUBWORD(@cmd_string, 1, 1);
- upcase_str_var(s);
- server_mode := NOT (s = 'EX');
-
- (*-----------------------------------------------------------------------*)
- (* Get options (if any) *)
- (*-----------------------------------------------------------------------*)
-
- opt_string := get_option_string(cmd_string);
-
- IF server_mode AND (opt_string = '') THEN
- BEGIN;
- IF s = 'EL' THEN
- opt_string := '[L]'
- ELSE
- opt_string := '[EKIZ]';
- END;
-
- upcase_str_var(opt_string);
-
- (*-----------------------------------------------------------------------*)
- (* See if valid parms *)
- (*-----------------------------------------------------------------------*)
-
- IF (words(cmd_string) < 2)
- OR (server_mode AND (words(cmd_string) < 3)) THEN
- BEGIN;
- send_message(message_not_en);
- active_tcb^.error_sw := TRUE;
- EXIT;
- END;
-
- (*-----------------------------------------------------------------------*)
- (* See if we can run. *)
- (*-----------------------------------------------------------------------*)
-
- IF (POS('A', opt_string) = 0) AND bbs_busy THEN
- BEGIN;
-
- {$IFDEF DEBUG}
- WRITELN('EX Busy');
- {$ENDIF}
-
- send_message(message_other_active);
- active_tcb^.error_sw := TRUE;
- wakeup_did_something := FALSE;
- EXIT;
-
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Initialize *)
- (*-----------------------------------------------------------------------*)
-
- save_cons := active_tcb^.tcb_console;
- save_port := active_port;
- save_pchn := active_tcb^.port_chan_s;
- active_tcb^.tcb_console := TRUE;
- active_port := @dummy_port;
- active_tcb^.tcb_port := active_port;
- active_tcb^.port_chan_s := 'EX';
-
- (*-----------------------------------------------------------------------*)
- (* Break out the names *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF DEBUG_2} (* Server names *)
- WRITELN;
- WRITELN('cmds = ', cmd_string);
- WRITELN('Servermode = ', server_mode);
- WRITELN('options = ', opt_string);
- DELAY(1000);
- {$ENDIF}
-
- IF server_mode THEN
- BEGIN;
- server_name := subword(@cmd_string, 2, 1);
- program_name := subword(@cmd_string, 3, 1);
- cmd_string := subword(@cmd_string, 4, 0);
- END
- ELSE
- BEGIN;
-
- program_name := subword(@cmd_string, 2, 1);
- cmd_string := subword(@cmd_string, 3, 0);
-
- i := POS('\', program_name);
- IF i = 0 THEN
- i := POS(':', program_name);
- IF i = 0 THEN
- i := 1;
-
- server_name := COPY(program_name, i, 255);
- i := POS('.', server_name);
- IF i > 1 THEN
- server_name := COPY(server_name, 1, i-1);
-
- END;
-
- {$IFDEF DEBUG_2} (* Server names *)
- WRITELN('server_name = ', server_name);
- WRITELN('program_name = ', program_name);
- WRITELN('cmd_string = ', cmd_string);
- DELAY(1000);
- {$ENDIF}
-
- {$IFDEF DEBUG_3} (* Server names *)
- send_data_tnc_str('Server = ' + server_name
- + '-- Program = ' + program_name+ cr);
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Do EXPORT as needed *)
- (*-----------------------------------------------------------------------*)
-
- IF POS('E', opt_string) > 0 THEN
- BEGIN;
-
- IF POS('K', opt_string) > 0 THEN
- s := 'EXPORTK '
- ELSE
- s := 'EXPORT ';
-
- {$IFDEF DEBUG_3} (* Server names *)
- send_data_tnc_str(s + server_name + '.IN E ' + server_name + cr);
- {$ENDIF}
-
- export_cmd(s + server_name + '.IN E ' + server_name, NIL);
-
- active_tcb^.error_sw := FALSE;
-
- END;
-
- (*-----------------------------------------------------------------------*)
- (* If no input file then we can skip *)
- (*-----------------------------------------------------------------------*)
-
- IF (POS('Q', opt_string) > 0)
- AND (file_test(server_name + '.IN') <> 0) THEN
- BEGIN;
- send_tnc_data_str('No input file for server. Operation terminated'
- + cr);
- EXIT;
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Resolve program name *)
- (*-----------------------------------------------------------------------*)
-
- upcase_str_var(program_name);
-
- IF program_name = 'DOS' THEN
- BEGIN;
- program_name := GETENV('COMSPEC');
- cmd_string := '/C ' + cmd_string;
- END
- ELSE
- program_name := FSEARCH(program_name, GETENV('PATH'));
-
- IF program_name = '' THEN
- BEGIN;
- send_message(message_dos_ex_file_nf);
- EXIT;
- END;
-
- (* program_name := FSEARCH(program_name, GETENV(s)); *)
-
- send_tnc_data_str('PGM = ' + program_name + cr);
- send_tnc_data_str('CMD = ' + cmd_string + cr);
-
- (*-----------------------------------------------------------------------*)
- (* Calculate swap size *)
- (*-----------------------------------------------------------------------*)
-
- swap_bot := active_tcb^.sptr_init;
- swap_bot := swap_bot DIV 16 + SSEG + 8;
-
- {$IFDEF VER55}
- swap_top := SEG(FREEPTR^) + $1000;
- {$ELSE}
- swap_top := SEG(HEAPEND^);
- {$ENDIF}
-
- swap_size := swap_top - swap_bot;
-
- {$IFDEF MEMSIZE}
- STR(LONGINT(swap_bot) * 16, s);
- send_tnc_data_str('Execute DOS -- Bottom = ' + s + cr);
-
- STR(LONGINT(swap_top) * 16, s);
- send_tnc_data_str('Execute DOS -- Top = ' + s + cr);
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Tell user we are running *)
- (*-----------------------------------------------------------------------*)
-
- STR(LONGINT(swap_size) * 16, s);
-
- {$IFDEF DEBUG}
- WRITELN('EX Send 1');
- {$ENDIF}
-
- send_tnc_data_str('Execute DOS processing started -- Memsize = '
- + s + cr);
-
- {$IFDEF DEBUG}
- WRITELN('EX Drain 1');
- {$ENDIF}
-
- send_drain;
-
- (*-----------------------------------------------------------------------*)
- (* Obtain the interrupt lock *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
- WRITELN('EX I Lock');
- {$ENDIF}
-
- get_semaphore(semaphore_interrupts, sem_exclusive, FALSE);
-
- (*-----------------------------------------------------------------------*)
- (* Open swap file *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF DEBUG}
- WRITELN('EX Swap open');
- {$ENDIF}
-
- ASSIGN(swap_file, 'SWAP.BB');
-
- {$I-}
- REWRITE(swap_file, 16);
- i := IORESULT;
- {$I+}
-
- IF i <> 0 THEN
- BEGIN;
- send_tnc_data_str('I/O error on SWAP output file' + cr);
- send_tnc_data_str(dos_err_message(i) + cr);
- clean_up;
- EXIT;
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Swap write out *)
- (*-----------------------------------------------------------------------*)
-
- j := swap_size;
- p := PTR(swap_bot, 0);
-
- {$IFDEF POINT_CHK}
- test_pointer(p);
- {$ENDIF}
-
- WHILE j >= max_block DO
- BEGIN;
- BLOCKWRITE(swap_file, p^, max_block);
- DEC(j, max_block);
- p := PTR(SEG(p^) + max_block, OFS(p^));
- END;
- IF j > 0 THEN
- BLOCKWRITE(swap_file, p^, j);
-
- (*-----------------------------------------------------------------------*)
- (* Swap write out complete *)
- (*-----------------------------------------------------------------------*)
-
- CLOSE(swap_file);
-
- {$IFDEF DEBUG}
- WRITELN('Swapout done');
- DELAY(1000);
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Shrink the memory size *)
- (*-----------------------------------------------------------------------*)
-
- WITH regs DO
- BEGIN
- AX := $4A00; (* DOS function 4Ah - SETBLOCK *)
- ES := PREFIXSEG; (* location of our memory block*)
- BX := swap_bot + overage - PREFIXSEG; (* Size we want *)
- MSDOS(regs);
- IF (FLAGS AND $0001) <> 0 THEN (* if carry is set then error *)
- BEGIN
- AX := $5900; (* DOS 59h - Get Extended Err *)
- MSDOS(regs);
- WRITELN('Critical error on DOS execute shrink');
- WRITELN('AX = ', AX, ' -- BH = ', bh, ' -- BL = ', bl);
- HALT;
- END
- END;
-
- {$IFDEF DEBUG}
- WRITELN('Shrink done');
- DELAY(1000);
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Execute *)
- (*-----------------------------------------------------------------------*)
-
- SWAPVECTORS;
- EXEC(program_name, cmd_string);
- SWAPVECTORS;
-
- {$IFDEF DEBUG}
- WRITELN('EXEC back');
- DELAY(1000);
- {$ENDIF}
-
- d_err := DOSERROR;
-
- (*-----------------------------------------------------------------------*)
- (* Grow the memory size *)
- (*-----------------------------------------------------------------------*)
-
- WITH regs DO
- BEGIN
- AX := $4A00; (* DOS function 4Ah - SETBLOCK *)
- ES := PREFIXSEG; (* location of our memory block*)
- BX := swap_top - PREFIXSEG; (* Size we want *)
- MSDOS(regs);
- IF (FLAGS AND $0001) <> 0 THEN (* if carry is set then error *)
- BEGIN
- AX := $5900; (* DOS 59h - Get Extended Err *)
- MSDOS(regs);
- WRITELN('Critical error on DOS execute grow');
- WRITELN('AX = ', AX, ' -- BH = ', bh, ' -- BL = ', bl);
- HALT;
- END
- END;
-
- {$IFDEF DEBUG}
- WRITELN('GROW done');
- DELAY(1000);
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Open swap file *)
- (*-----------------------------------------------------------------------*)
-
- {$I-}
- RESET(swap_file, 16);
- i := IORESULT;
- {$I+}
-
- IF i <> 0 THEN
- BEGIN;
- send_tnc_data_str('I/O error on SWAP input file' + cr);
- send_tnc_data_str(dos_err_message(i) + cr);
- RUNERROR(swp_error);
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Swap read in *)
- (*-----------------------------------------------------------------------*)
-
- j := swap_size;
- p := PTR(swap_bot, 0);
-
- {$IFDEF POINT_CHK}
- test_pointer(p);
- {$ENDIF}
-
- WHILE j >= max_block DO
- BEGIN;
- BLOCKREAD(swap_file, p^, max_block);
- DEC(j, max_block);
- p := PTR(SEG(p^) + max_block, OFS(p^));
- END;
- IF j > 0 THEN
- BLOCKREAD(swap_file, p^, j);
-
- {$IFDEF DEBUG}
- WRITELN('SWAP in done');
- DELAY(1000);
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Swap read in complete *)
- (*-----------------------------------------------------------------------*)
-
- CLOSE(swap_file);
- ERASE(swap_file);
-
- IF d_err = 2 THEN
- BEGIN;
- send_message(message_file_no_exist);
- active_tcb^.error_sw := TRUE;
- clean_up;
- EXIT;
- END;
-
- IF d_err = 8 THEN
- BEGIN;
- send_tnc_data_str('Not enough memory' + cr);
- send_flush;
- active_tcb^.error_sw := TRUE;
- clean_up;
- EXIT;
- END;
-
- IF d_err <> 0 THEN
- BEGIN;
- WRITELN('Critical error on DOS execute -- ', d_err);
- HALT;
- END;
-
- (*-----------------------------------------------------------------------*)
- (* clock update *)
- (*-----------------------------------------------------------------------*)
-
- time_check;
-
- {$IFDEF DEBUG}
- WRITELN('Time check done');
- DELAY(1000);
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Force window things *)
- (*-----------------------------------------------------------------------*)
-
- status_window_change := TRUE;
-
- (*-----------------------------------------------------------------------*)
- (* Clean things up *)
- (*-----------------------------------------------------------------------*)
-
- clean_up;
-
- {$IFDEF DEBUG}
- WRITELN('cleanup done');
- DELAY(1000);
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Rewrite windows *)
- (*-----------------------------------------------------------------------*)
-
- i := who_is_in_window(window_top_screen);
- window_select(i);
- CLRSCR;
- window_refresh(i);
-
- i := who_is_in_window(window_bottom_screen);
- window_select(i);
- window_refresh(i);
-
- {$IFDEF DEBUG}
- WRITELN('Window done');
- DELAY(1000);
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Tell user we are done *)
- (*-----------------------------------------------------------------------*)
-
- send_tnc_data_str('DOS processing ended' + cr);
-
- IF active_tcb^.error_sw THEN
- BEGIN;
- send_tnc_data_str('DOS program terminated with error' + cr);
- send_flush;
- EXIT;
- END;
-
- send_flush;
-
- (*-----------------------------------------------------------------------*)
- (* Do reload as needed *)
- (*-----------------------------------------------------------------------*)
-
- IF POS('L', opt_string) > 0 THEN
- BEGIN;
-
- cmd_string := 'GL';
- oper_gm(cmd_string);
-
- active_tcb^.error_sw := FALSE;
-
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Do IMPORT as needed *)
- (*-----------------------------------------------------------------------*)
-
- IF POS('I', opt_string) > 0 THEN
- BEGIN;
-
- IF POS('Z', opt_string) > 0 THEN
- s := 'IMPORTES '
- ELSE
- s := 'IMPORTS ';
-
- cmd_string := s + server_name + '.OUT';
-
- {$IFDEF DEBUG_3} (* Server names *)
- send_data_tnc_str(cmd_string + cr);
- {$ENDIF}
-
- import_cmd(cmd_string);
-
- active_tcb^.error_sw := FALSE;
-
- END;
-
- END;
-
- END.